
// 导入 Vue 构造函数
import Vue from 'vue'
import ElementUI from 'element-ui'


// 导入样式重置文件(样式统一化)
import 'normalize.css/normalize.css' // A modern alternative to CSS resets

// 导入 ElementUI 组件库
// 导入 ElementUI 组件库的样式
import 'element-ui/lib/theme-chalk/index.css'
// 导入 ElementUI 英文语言包
// import locale from 'element-ui/lib/locale/lang/en' // lang i18n
// @：src的别名、也是src的绝对路径
// 导入全局样式,为什么这里只导入一个?因为index.scss中导入了另外5个样式文件
import '@/styles/index.scss' // global css

// 导入根组件
import App from './App.vue'
// 导入 store 模块
import store from './store'
// 导入 router 模块
import router from './router'

// 导入 svg 图标
import '@/icons' // icon
// 导入 权限控制模块
import '@/permission' // permission control

// 导入 自定义 模块
import '@/directives'
// 导入 打印插件
import Print from 'vue-print-nb'
// 注册插件 -> 提供全局 v-print 指令用来打印指定的盒子内容
Vue.use(Print)
import i18n from '@/lang'
// 配置ElementUI的中英切换逻辑
Vue.use(ElementUI, {
  i18n: (key, value) => {
    return i18n.t(key, value)
  }
})

// 导入插件对象
import My from './plugin'
// 注册插件
Vue.use(My)

// 取消控制台的一句提示
Vue.config.productionTip = false

// 实例化 Vue 实例
new Vue({
  // 注入 router
  router,
  // 注入 store
  store,
  i18n,
  // 渲染根组件
  render: h => h(App)
}).$mount('#app')// 渲染到id=app的div的位置

// 跨域及解决方案：
// 跨域：出于浏览器同源策略的限制(安全的角度),不能请求非同源接口的数据
// 同源的3个必备条件：协议 + 域名 + 端口
// 1. jsonp(基本废弃)
// 2. cors(跨域资源共享,需要后端配合,设置一个响应头字段即可)
// 3. 代理

// 1. 假如你上班的第一天,领导给了你一个新的项目,你如何启动？
// 答： package.json -> scripts
// 2. 我们的项目是自己从零开始的么?如果不是，用的什么模板(架子)？
// 答：不是，vue-element-admin(完整版 -> 参考代码价值)
//         vue-admin-template(简化版 -> 适合二次开发)
// 3. 项目的亮点是什么?基于的核心思想是什么?
// 答：权限控制; RBAC(给员工分配角色、给角色分配权限)
// 4. 三个.env开头的文件作用是什么?
// 答：环境变量的配置;不同环境(执行不同的命令)下会取不同的环境变量值(灵活，不动手动改来改去)

// 自定义指令：
// 作用：操作原生的DOM的时候
// 分类：全局(主要的)和局部
// 语法：2步：
// 1. 定义指令
Vue.directive('指令名', {
  // 插入到真实DOM中时自动触发一次
  inserted (el, binding) {
    // 今后指令作用在哪个标签上，el就是这个标签的DOM对象
    // 指令可以绑定表达式，如何获取表达式的值 -> binding.value
    // el.innerHTML = binding.value
    // 这里可以对el做任何原生DOM操作
  },
  // 指令绑定表达式的值变了，每次都会自动触发
  update (el, binding) {
    // el.innerHTML = binding.value
    // 这里可以对el做任何原生DOM操作
  }
})
// 2. 调用指令 -> 在标签上作用指令

// 知识点：数组的 some 方法
// 语法：arr.some((item, index) => {})
// 作用：检测数组中是否有满足条件的元素，
//      只要有一个满足的条件，立即则返回true，停止查找；否则返回fals

// const arr = [1, 2, 3, 4, 5]
// const ret = arr.some((item) => {
//   console.log('some')
//   if (item > 6) {
//     return true
//   } else {
//     return false
//   }
// })

// const ret = arr.some((item) => item > 6)
// console.log(ret)

// 数组 indexOf、includes、find 三个方法区别
// 相同点：都可以检测数组中是否存在某个元素
// 不同点：
// 1. 适用范围不同
// A.（indexOf/includes只适用基本类型数组的检测，比如：数字、字符串数组）
// B. 对象数组的检测只能用find
// 2. 返回值不同
// indexOf: 返回是下标数字，如果返回-1，说明不存在这个元素
// includes: 返回布尔值，存在返回true；否则返回false
// find：如果存在，返回相应的元素；否则返回 undefined

// const arr = [33, 44, 55, 66]
// console.log(arr.indexOf(55))// 2
// console.log(arr.includes(55))// true
// console.log(arr.find((item) => item === 55))// 55

// console.log(arr.indexOf(77))// -1
// console.log(arr.includes(77))// false
// console.log(arr.find((item) => item === 77))// undefined

// const goodsList = [
//   { id: 101, name: '篮球' },
//   { id: 202, name: '足球' },
//   { id: 303, name: '排球' }
// ]

// console.log(goodsList.indexOf(202))// -1
// console.log(goodsList.includes(202))// false
// console.log(goodsList.find(item => item.id === 202))// { id: 202, name: '足球' }

// Object.keys(obj)：取出所有键的数组，因为是数组，我们有很多
// 数组的操作的方法，比如：sort、filter等，灵活性很强
// 代替for-in循环

// 项目总结：
// 1. 项目如何架构的（采用的技术 + 主要模块）

// 2. 登录成功的token如何管理的？
// 通过 vuex + cookie 配合管理
//  1. cookie： 负责token持久化、刷新不丢失
//  2. vuex：负责token的操作(获取、删除、设置)
//  vuex的优势：1. 操作速度与cookie快(vuex操作内存中，cookie操作的磁盘) 2. vuex中的数据是响应式的

// 3. token的过期处理？
//  1. 处理时机：响应拦截器（因为所有的请求失败都会经过这里）
//  2. 如何处理：
//   1. 检测401的http状态码
//   2. 清空token和用户信息
//   3. 重新登录

// 4. 登录拦截处理？
//  1. 处理时机：路由的全局前置守卫 -> router.beforeEach(() => { })
//  2. 如何处理：
    // 1. 检测有无token
    //  1. 如果有：
    //   1. 是否去登录，如果是，则停留在原地 -> next(false)
    //   2. 否则，直接放行 -> next()
    // 2. 没有
    //   1. 检测是否访问白名单中的路由，如果是，直接放行
    //   2. 否则，跳转至登录，并携带要去的路由路径，便于做回跳

// 5. 项目中跨域如何解决？
// 方案：代理解决跨域
// 原理：自己搞一个服务器、因为服务器与服务器之间请求是不存在跨域的，因为跨域是浏览器出于安全
        // 角度做出的一种限制，也叫同源策略
// 流程：axios -> 自己的服务器(不存在跨域) -> 自己的服务器内部悄悄滴做个转发(抵达目标服务器)
// 配置：
// 1. 开发环境下：基于webpack开发服务器解决，vue.config.js -> devSever -> proxy
// 2. 生产环境下：配置服务器代理，拦截请求路径 -> 转发至目标服务器

// 6. 数据处理
//   1. 数组与树的互转 -> 函数的递归
//   2. Excel导入和导出数据格式转换 -> 中英文键的映射

// 7. RBAC权限控制如何实现？
// 目标：不同的员工/用户，登录成功后看到的主页菜单不同
// 思想：给员工分配角色、给角色分配权限，这样不同的员工就拥有了不同的权限
// 原理：
//  1. 路由表分为静态路由表和动态路由表
//  2. 在路由全局前置守卫中，跳转至主页之前、获取用户信息，拿到用户拥有的权限列表
//  3. 基于权限列表对动态路由表做筛选，把筛选后的结果通过 addRoutes() 添加至路由表
//  4. 在vuex中动态管理路由表，目的做当路由表变了，可以把路由表最新的结果展示到左侧菜单上
//  5. 因为左侧菜单是基于路由表递归生成的
//  6. 细节：
//   1. 防止刷新会404，需要把 { path: '*', redirect: '/404', hidden: true } 放置路由表末尾
//   2. 防止刷新白屏，需要在 addRoutes() 之后，重新进入当前路由一次
//   3. 退出登录时，重置路由实例和vuex路由表信息
//   4. 为什么有些菜单在左侧菜单出现，有些不出现，因为配置了hidden为true，配合v-if做条件渲染

// 8. 按钮的操作权如何控制？
// 目标：不同的员工/用户，虽然能访问路由，但不同给他开放对应的按钮操作权
// 原理：检测用户信息中是否存在相应的操作权限点标识，如果有，则开放：
// 1. 是否禁用 -> 配置 disabled 属性
// 2. 是否渲染 -> 配和 v-if 做条件渲染
// 3. 在触发执行按钮逻辑之前，做个判断拦截

// 9. 封装业务组件？
// 开发思想：组件化
// 设计/封装组件的目的：解决视图重用的问题
// 设计一个好的组件，需要考虑四个点：
// 1. props -> 父传子的数据 
// 2. events -> 监听的事件
// 3. slots ->  允许用户自定义组件模板标签
// 4. methods -> 方法、给程序员提供的便捷操作方法

// 10. Vue.use()？
// 作用：注册插件 -> 增强/扩展Vue的能力
// 原理：插件对象必须提供 install(Vue) 方法
// 能干啥：1. 注册全局组件  2. 注册全局指令  3. 添加原型方法  4. 注册全局过滤器

// 11. v-model的原理？
// v-model只是个语法糖，内部干了两个指令的事情
// v-model本质： = v-bind:value + v-on:input







